package com.coconutwater.nft.block;

import com.coconutwater.nft.NFTMod;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.block.Block;
import net.minecraft.block.BlockRailBase;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.item.EntityMinecart;
import net.minecraft.util.IIcon;
import net.minecraft.world.World;

/**
 * Created by Coconutwater on 16/10/3.
 */
public class BlockRailTransfer extends BlockRailBase {
    public static final String UNLOCALIZED_NAME = "nft_rail";

    public BlockRailTransfer() {
        super(false);
        this.setCreativeTab(CreativeTabs.tabTransport);
        setHardness(0.7F).setStepSound(soundTypeMetal).setBlockName(UNLOCALIZED_NAME).setBlockTextureName(NFTMod.MODID + ":" + UNLOCALIZED_NAME);

    }

    @SideOnly(Side.CLIENT)
    @Override
    public IIcon getIcon(int side, int meta) {
        return this.blockIcon;
    }


    @Override
    public void onMinecartPass(World world, EntityMinecart cart, int x, int y, int z) {
        super.onMinecartPass(world, cart, x, y, z);

        BlockPos blockPos = findClosestNFTBlock(world, cart, x, y, z);
        cart.setPosition(blockPos.getX(), blockPos.getY(), blockPos.getZ());
        cart.setCurrentCartSpeedCapOnRail(1.2F);

    }
    //TODO 防止不是单个铁轨的情况

    private BlockPos findClosestNFTBlock(World world, EntityMinecart cart, int x, int y, int z) {
        // x -x y -y z -z
        int type = getPriorityDir(cart);
        return getCloseBlockPos(world, x, y, z, type);
    }

    private BlockPos getCloseBlockPos(World world, int x, int y, int z, int type) {
        int radius = NFTMod.RADIUS;
        boolean isX = (type == 0 || type == 1);
        boolean isPositive = type % 2 == 0;
        int thisId = Block.getIdFromBlock(this);
        int bottomId = Block.getIdFromBlock(world.getBlock(x, y - 1, z));
        if (isX) {
            if (isPositive) {
                for (int k = y - radius; k < y + radius; k++) {
                    for (int i = x - 1; i > x - radius; i--) {
                        for (int j = z - radius; j < z + radius; j++) {
                            if ((Block.getIdFromBlock(world.getBlock(i, k, j)) == thisId) && (Block.getIdFromBlock(world.getBlock(i, k - 1, j)) == bottomId)) {
                                return new BlockPos(i - 1, k + 1, j);
                            }

                        }
                    }
                }
            } else {
                for (int k = y - radius; k < y + radius; k++) {
                    for (int i = x + 1; i < x + radius; i++) {
                        for (int j = z - radius; j < z + radius; j++) {
                            if ((Block.getIdFromBlock(world.getBlock(i, k, j)) == thisId) && (Block.getIdFromBlock(world.getBlock(i, k - 1, j)) == bottomId)) {
                                return new BlockPos(i + 1, k + 1, j);
                            }

                        }
                    }
                }
            }

        } else {
            if (isPositive) {
                for (int k = y - radius; k < y + radius; k++) {
                    for (int j = z - 1; j > z - radius; j--) {
                        for (int i = x - radius; i < x + radius; i++) {
                            if ((Block.getIdFromBlock(world.getBlock(i, k, j)) == thisId) && (Block.getIdFromBlock(world.getBlock(i, k - 1, j)) == bottomId)) {
                                return new BlockPos(i, k + 1, j - 1);
                            }

                        }
                    }
                }
            } else {
                for (int k = y - radius; k < y + radius; k++) {
                    for (int j = z + 1; j < z + radius; j++) {
                        for (int i = x - radius; i < x + radius; i++) {
                            if ((Block.getIdFromBlock(world.getBlock(i, k, j)) == thisId) && (Block.getIdFromBlock(world.getBlock(i, k - 1, j)) == bottomId)) {
                                return new BlockPos(i, k + 1, j + 1);
                            }

                        }
                    }
                }
            }
        }


        return new BlockPos(x, y, z);
    }

    private int getPriorityDir(EntityMinecart cart) {
        int type = 0;
        double diffX = cart.prevPosX - cart.posX;
        double diffY = cart.prevPosY - cart.posY;
        double diffZ = cart.prevPosZ - cart.posZ;
        double absdiffX = Math.abs(diffX);
        double absdiffY = Math.abs(diffY);
        double absdiffZ = Math.abs(diffZ);
        double max = (absdiffX < absdiffY ? (absdiffY < absdiffZ ? absdiffZ : absdiffY) : (absdiffX < absdiffZ ? absdiffZ : absdiffX));
        if (max - absdiffX < 0.001) {
            type = diffX > 0 ? 0 : 1;
        } else if (max - absdiffY < 0.001) {
            type = diffY > 0 ? 2 : 3;
        } else if (max - absdiffZ < 0.001) {
            type = diffZ > 0 ? 4 : 5;
        }
        return type;
    }


    class BlockPos {
        int x;
        int y;
        int z;

        public BlockPos(int x, int y, int z) {
            this.x = x;
            this.y = y;
            this.z = z;
        }

        public int getX() {
            return x;
        }

        public int getY() {
            return y;
        }

        public int getZ() {
            return z;
        }
    }
}
